//------------------------------------------------------------------------------
//	file sm.h
//	brief
//		State machine declaration file
//
//  $Id: sm.h 235 2014-01-14 02:54:35Z ac.verbeck@gmail.com $
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//	Copyright and Disclaimer Notice
//
//	Copyright (c) 2012 A.C. Verbeck
//
//	This file is part of SM: A State Machine Library.
//
//	SM is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	SM is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with SM.  If not, see <http://www.gnu.org/licenses/>.
//
//------------------------------------------------------------------------------
#pragma once

//------------------------------------------------------------------------------
//  Typedef variables for state machine
//------------------------------------------------------------------------------
typedef uint32_t	SM_EVENT;													//  Events passed to state machine
typedef uint32_t	SM_STATE;													//  Current state
typedef enum {
	SM_OK,																		//	State machine is running well
	SM_ERROR,																	//	State machine error
	SM_SC_ERROR																	//	State machine state count error
} SM_STATUS;																	//  Current status of the state machine

//------------------------------------------------------------------------------
//  Typedef structures for state machine
//------------------------------------------------------------------------------
typedef struct {
	SM_STATUS(*enter)(void);													//	Enter function
	SM_STATUS(*process)(SM_EVENT ev);											//	Processing function
	SM_STATUS(*exit)(void);														//	Exit function
} SM_STATE_FN;

//------------------------------------------------------------------------------
//  Typedef structures for state machine
//------------------------------------------------------------------------------
typedef struct {
	SM_STATE	c_state;														//	SM state
	SM_STATE	n_state;														//	SM next state
	SM_STATE	p_state;														//	SM last state
} STATE_INIT;

//------------------------------------------------------------------------------
//  Class declaration
//------------------------------------------------------------------------------
class SM
{

private:
	SM_STATE		c_state;													//	SM state
	SM_STATE		n_state;													//	SM next state
	SM_STATE		p_state;													//	SM last state
	uint32_t		m_state;													//	Max size of state array: so we don't go off the end
	SM_STATUS		status;														//	SM status
	bool			change;														//	Change state
	SM_STATE_FN*	st_arr;														//	allocate state array

public:
	SM(const SM_STATE_FN st[], uint32_t ms, STATE_INIT* si);
	~SM(void);

	SM_STATUS	Process(SM_EVENT ev);
	SM_STATUS	StateChange(SM_STATE st);
	SM_STATUS	StatePrev(void);

	SM_STATE	GetState(void);
	SM_STATUS	GetStatus(void);
};

//
//	End: sm.h
//
